"""
主应用文件
用于整合各个路由模块并启动FastAPI应用
"""

# 导入系统模块
import sys
import os

# 将项目根目录添加到Python路径中
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

# 导入FastAPI框架及相关组件
from fastapi import FastAPI, Request, Response
from fastapi.middleware.cors import CORSMiddleware
from dotenv import load_dotenv
from datetime import datetime

# 导入各个路由模块
from routers import auth, files, workflows, data, results, ai, admin

# 加载环境变量
load_dotenv()

# 初始化FastAPI应用
app = FastAPI(
    title="免疫数据平台",
    description="为免疫数据平台开发的后端API服务",
    version="1.0.0"
)

# 配置CORS中间件，允许跨域请求
app.add_middleware(
    CORSMiddleware,
    allow_origins=["http://localhost:5000"],  # 在生产环境中应该指定具体的域名
    allow_credentials=True,
    allow_methods=["GET", "POST", "PUT", "DELETE", "OPTIONS"],
    allow_headers=["*"],
    expose_headers=["*"],
    max_age=3600  
)

# 操作日志中间件 - 记录所有管理接口的访问日志
@app.middleware("http")
async def log_operations(request: Request, call_next):
    """
    操作日志记录中间件
    用于记录所有管理接口(/api/v1/admin/)的访问日志，包括请求方法、路径、IP地址等信息
    Args:
        request (Request): HTTP请求对象，包含请求的所有信息
        call_next (Callable): 调用下一个中间件或路由处理函数的回调函数
    Returns:
        Response: HTTP响应对象，返回给客户端的响应
    """
    # 获取请求的基本信息
    method = request.method                    # HTTP请求方法 (GET, POST, PUT, DELETE等)
    path = request.url.path                   # 请求路径
    
    # 检查是否为管理接口路径，只有管理接口才记录日志
    if path.startswith("/api/v1/admin/"):
        # 获取用户信息（在实际项目中应该从认证信息中获取真实的用户ID和用户名）
        user_id = 1                           # 示例用户ID，实际应从JWT token中解析
        username = "admin"                    # 示例用户名，实际应从JWT token中解析
        
        # 获取客户端IP地址
        # 首先尝试从X-Forwarded-For头部获取（适用于使用反向代理的情况）
        forwarded_for = request.headers.get("X-Forwarded-For")
        if forwarded_for:
            # X-Forwarded-For可能包含多个IP地址，取第一个（最原始的客户端IP）
            ip_address = forwarded_for.split(",")[0].strip()
        else:
            # 如果没有X-Forwarded-For头部，则尝试从X-Real-IP头部获取
            real_ip = request.headers.get("X-Real-IP")
            if real_ip:
                ip_address = real_ip
            else:
                # 如果都没有，则从请求的客户端信息中获取
                ip_address = request.client.host if request.client else "unknown"
        
        # 获取用户代理信息（浏览器或其他客户端信息）
        user_agent = request.headers.get("User-Agent", "")
        
        # 获取数据库会话，用于保存操作日志
        from models import SessionLocal
        db = SessionLocal()
        
        try:
            # 创建操作日志记录对象
            from models import OperationLog as OperationLogModel
            log_entry = OperationLogModel(
                user_id=user_id,                                    # 用户ID
                username=username,                                  # 用户名
                operation_type=f"{method}_REQUEST",                 # 操作类型，格式为"方法_REQUEST"
                description=f"访问 {method} {path}",                # 操作描述
                method=method,                                      # HTTP请求方法
                path=path,                                          # 请求路径
                ip_address=ip_address,                              # 客户端IP地址
                user_agent=user_agent                               # 用户代理信息
            )
            
            # 将操作日志记录保存到数据库
            db.add(log_entry)
            db.commit()
        except Exception as e:
            # 如果记录日志过程中出现异常，回滚事务并打印错误信息
            db.rollback()
            print(f"记录操作日志失败: {e}")
        finally:
            # 关闭数据库会话，释放资源
            db.close()
    
    # 继续处理请求，调用下一个中间件或路由处理函数
    response = await call_next(request)
    return response

# 注册各个路由模块
app.include_router(auth.router)
app.include_router(files.router)
app.include_router(workflows.router)
app.include_router(data.router)
app.include_router(results.router)
app.include_router(ai.router)
app.include_router(admin.router)

@app.get("/")
def root():
    """
    根路径
    Returns:
        dict: 欢迎信息
    """
    return {"message": "欢迎使用免疫数据平台API服务"}

# 应用入口
if __name__ == "__main__":
    import uvicorn
    # 启动应用服务器
    uvicorn.run(app, host="localhost", port=3000)